﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Experimental.VFX;
using Windows.Kinect;

public class KinectInputPointer : MonoBehaviour
{

    #region 转换坐标用的四个顶点4

    //这几个位置填的是Kinect中获取的屏幕的左下和右上顶点，也就是Kinect镜头坐标的数值
    // [SerializeField] Vector2 leftDown;
    // [SerializeField] Vector2 rightUp;

    // [SerializeField] const float world = 1920;
    // [SerializeField] const float screenHight = 1080;

    private Vector2 ori;
    private float xMultiplier;
    private float yMultiplier;

    #endregion

    [SerializeField] VisualEffect vfx;

    GameObject rightHand;
    private KinectSensor _Sensor;
    private BodyFrameReader _Reader;
    private Body[] _Data = null;

    private float timeDelta = 0;

    HashSet<ulong> _Bodies = new HashSet<ulong> ();

    void Start ()
    {
        _Sensor = KinectSensor.GetDefault ();

        if (_Sensor != null)
        {
            _Reader = _Sensor.BodyFrameSource.OpenReader ();

            if (!_Sensor.IsOpen)
            {
                _Sensor.Open ();
            }
        }
    }

    void Update ()
    {
        timeDelta += Time.deltaTime;
        #region 获取BodyFrame
        if (_Reader != null)
        {
            var frame = _Reader.AcquireLatestFrame ();

            if (frame != null)
            {
                if (_Data == null)
                {
                    _Data = new Body[_Sensor.BodyFrameSource.BodyCount];
                }

                frame.GetAndRefreshBodyData (_Data);

                frame.Dispose ();
                frame = null;
            }
        }
        #endregion

        if (_Data == null)
            return;

        #region 去除废弃的Body
        var trackedIds = new List<ulong> ();
        //遍历Body
        foreach (var body in _Data)
        {
            if (body != null && body.IsTracked)
            {
                //向数组添加追踪的Body
                trackedIds.Add (body.TrackingId);
            }
        }

        List<ulong> knownIds = new List<ulong> (_Bodies);

        // 剔除未被追踪的身体
        foreach (ulong trackingId in knownIds)
        {
            if (!trackedIds.Contains (trackingId))
            {
                //如果trackedIds里没有trackingId，就把Body里的删掉
                _Bodies.Remove (trackingId);
            }
        }

        foreach (var body in _Data)
        {
            if (body == null)
            {
                continue;
            }

            if (body.IsTracked)
            {
                if (!_Bodies.Contains (body.TrackingId))
                {
                    _Bodies.Add (body.TrackingId);
                }
                //输出关节的屏幕位置
                SimKinectPosition (body);
            }

        }
        #endregion
    }

    //其实用不用都差不多吧
    private void OnApplicationQuit ()
    {
        if (_Reader != null)
        {
            _Reader.Dispose ();
            _Reader = null;
        }

        if (_Sensor != null)
        {
            if (_Sensor.IsOpen)
            {
                _Sensor.Close ();
            }

            _Sensor = null;
        }
    }

    private static Vector3 GetVector3FromJoint (Windows.Kinect.Joint joint)
    {
        return new Vector3 (joint.Position.X * 10, joint.Position.Y * 10, joint.Position.Z * 10);
    }

    //Unity里的一个单位是1m，Kinect的一个单位也是1m，那不是可以直接用了吗...
    private void SimKinectPosition (Body body)
    {
        if (timeDelta > 0.7)
        {
            Debug.LogError (body.Joints[JointType.HandLeft].TrackingState);
            timeDelta = 0;
        }

        if (body.Joints[JointType.HandRight].TrackingState != 0 && rightHand == null)
        {
            rightHand = Instantiate (Resources.Load<GameObject> ("parti"), new Vector3 (body.Joints[JointType.HandRight].Position.X * 4.5f, body.Joints[JointType.HandRight].Position.Y * 6f, 5), Quaternion.identity);
        }

        if (rightHand != null && body.Joints[JointType.HandRight].TrackingState != 0)
        {
            rightHand.transform.position = new Vector3 (body.Joints[JointType.HandRight].Position.X * 4.5f, body.Joints[JointType.HandRight].Position.Y * 6f, 5);
        }

    }

    private Vector3 KCameraToWorld ()
    {
        return Vector3.zero;
    }

}